package xin.ryven.car.android

import android.animation.ValueAnimator
import android.annotation.SuppressLint
import android.app.DownloadManager
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.content.res.ColorStateList
import android.graphics.BitmapFactory
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.GradientDrawable
import android.graphics.drawable.LayerDrawable
import android.graphics.drawable.ScaleDrawable
import android.media.AudioManager
import android.os.Build
import android.os.Bundle
import android.os.Environment
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.view.Gravity
import android.view.KeyEvent
import android.view.View
import android.view.WindowInsets
import android.view.WindowInsetsController
import android.view.animation.AccelerateDecelerateInterpolator
import android.widget.PopupMenu
import android.widget.RadioButton
import android.widget.SeekBar
import android.widget.TextView
import android.widget.Toast
import androidx.activity.OnBackPressedCallback
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import androidx.core.net.toUri
import androidx.core.view.GravityCompat
import androidx.core.widget.CompoundButtonCompat
import androidx.drawerlayout.widget.DrawerLayout
import androidx.media3.common.MediaItem
import androidx.media3.common.PlaybackException
import androidx.media3.common.Player
import androidx.media3.common.util.UnstableApi
import androidx.media3.exoplayer.ExoPlayer
import androidx.recyclerview.widget.LinearLayoutManager
import com.google.android.material.dialog.MaterialAlertDialogBuilder
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import xin.ryven.car.android.adapter.MusicAdapter
import xin.ryven.car.android.adapter.DislikedAdapter
import xin.ryven.car.android.api.ApiService
import xin.ryven.car.android.data.Music
import xin.ryven.car.android.data.Playlist
import xin.ryven.car.android.data.Cover
import xin.ryven.car.android.databinding.ActivityPlayerBinding
import xin.ryven.car.android.download.FileDownloader
import xin.ryven.car.android.utils.ColorUtils
import xin.ryven.car.android.utils.FileUtils
import xin.ryven.car.android.utils.FontUtils
import xin.ryven.car.android.utils.LocalStorage
import xin.ryven.car.android.network.NetworkConfig
import java.io.File
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
import java.util.concurrent.TimeUnit
import android.os.StatFs


@UnstableApi
class PlayerActivity : AppCompatActivity() {
    companion object {
        private const val PREFS_NAME = "PlayerPrefs"
        private const val KEY_LAST_MUSIC_ID = "last_music_id"
        private const val KEY_LAST_POSITION = "last_position"
        private const val KEY_LAST_PLAYLIST_ID = "last_playlist_id"  // 添加保存最后使用的歌单ID
        private const val KEY_PLAY_MODE = "play_mode"
        private const val KEY_SHUFFLE_ENABLED = "shuffle_enabled"
        private const val KEY_GLOBAL_SHUFFLE_MODE = "global_shuffle_mode"
    }

    private lateinit var binding: ActivityPlayerBinding
    private lateinit var musicAdapter: MusicAdapter
    private val scope = CoroutineScope(Dispatchers.Main + Job())
    private var musicList = listOf<Music>()
    private var downloadedMusicList = mutableListOf<Music>()  // 新增：已下载音乐列表
    private var player: ExoPlayer? = null
    private var currentMusic: Music? = null
    
    // API服务（需要认证）
    private val apiService: ApiService by lazy {
        NetworkConfig.getApiService(this)
    }

    private var lastBackPressTime = 0L
    private val backPressInterval = 2000L  // 2秒内连按两次返回键退出
    private var updateDownloadId: Long = -1
    private var currentPlaylist: Playlist? = null
    private var allPlaylists: List<Playlist> = emptyList()
    private var allCovers: List<Cover> = emptyList()  // 新增：保存所有封面信息
    private var lastUsedCoverId: Int? = null  // 新增：记录上次使用的封面ID，避免连续使用同一张
    private val timeHandler = Handler(Looper.getMainLooper())
    private val timeRunnable = object : Runnable {
        override fun run() {
            updateDateTime()
            timeHandler.postDelayed(this, 60000) // 每分钟更新一次
        }
    }

    // 新增：侧边栏状态管理
    private var isSidebarVisible = true
    private val playlistTabs = mutableListOf<TextView>()

    private val onDownloadComplete = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            if (intent.action == DownloadManager.ACTION_DOWNLOAD_COMPLETE) {
                val id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
                if (id == updateDownloadId) {
                    val downloadManager =
                        getSystemService(DOWNLOAD_SERVICE) as DownloadManager
                    val query = DownloadManager.Query().setFilterById(id)
                    val cursor = downloadManager.query(query)

                    if (cursor.moveToFirst()) {
                        val status =
                            cursor.getInt(cursor.getColumnIndexOrThrow(DownloadManager.COLUMN_STATUS))
                        if (status == DownloadManager.STATUS_SUCCESSFUL) {
                            // 获取下载的文件
                            showInstallPrompt()
                        }
                    }
                    cursor.close()
                }
            }
        }
    }

    private enum class PlayMode {
        SEQUENCE,    // 顺序播放
        REPEAT_ONE,  // 单曲循环
        SHUFFLE      // 随机播放
    }

    private var currentPlayMode = PlayMode.SEQUENCE
    private var isShuffleEnabled = false
    private var shuffleOrder: MutableList<Int> = mutableListOf()
    private var isGlobalShuffleMode = false
    private var globalDownloadedMusicList = mutableListOf<Music>()
    private var globalShuffleOrder: MutableList<Int> = mutableListOf()
    private var dislikedMusicIds = mutableSetOf<Int>()
    private var prevSidebarVisibleInGlobal = true

    private var progressAnimator: ValueAnimator? = null
    private var volumeAnimator: ValueAnimator? = null

    // 添加播放历史记录
    private val playHistory = mutableListOf<Music>()
    private var historyIndex = -1
    private val maxHistorySize = 50  // 限制历史记录大小

    private var settingsDrawerView: View? = null
    private var dislikedDrawerView: View? = null
    private var drawerListener: DrawerLayout.DrawerListener? = null
    private var isCreatingSettingsDrawer = false
    private var loadingDialog: androidx.appcompat.app.AlertDialog? = null

    // 新增：防止重复点击的标志
    private var isCoverSwitching = false

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // 如果不是从根Activity启动，则直接结束
        if (!isTaskRoot && intent.hasCategory(Intent.CATEGORY_LAUNCHER)) {
            finish()
            return
        }

        binding = ActivityPlayerBinding.inflate(layoutInflater)
        setContentView(binding.root)

        // 在 setContentView 之后设置系统UI
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            // Android 11 (API 30) 及以上版本
            window.setDecorFitsSystemWindows(false)
            window.insetsController?.let { controller ->
                controller.hide(WindowInsets.Type.systemBars())
                controller.systemBarsBehavior =
                    WindowInsetsController.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
            }
        } else {
            // Android 10 (API 29) 及以下版本
            @Suppress("DEPRECATION")
            window.decorView.systemUiVisibility = (
                    View.SYSTEM_UI_FLAG_FULLSCREEN
                            or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                            or View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                    )
        }

        // 添加返回键处理
        onBackPressedDispatcher.addCallback(this, object : OnBackPressedCallback(true) {
            override fun handleOnBackPressed() {
                when {
                    binding.drawerLayout.isDrawerOpen(GravityCompat.START) -> {
                        binding.drawerLayout.closeDrawer(GravityCompat.START)
                    }

                    binding.drawerLayout.isDrawerOpen(GravityCompat.END) -> {
                        binding.drawerLayout.closeDrawer(GravityCompat.END)
                    }

                    else -> {
                        if (System.currentTimeMillis() - lastBackPressTime < backPressInterval) {
                            moveTaskToBack(true)
                        } else {
                            lastBackPressTime = System.currentTimeMillis()
                            Toast.makeText(
                                this@PlayerActivity,
                                "再按一次退出应用",
                                Toast.LENGTH_SHORT
                            ).show()
                        }
                    }
                }
            }
        })

        // 应用自定义字体
        binding.apply {
            FontUtils.apply(tvTitle)
            FontUtils.apply(tvArtist)
            FontUtils.apply(tvCurrentDateTime)
            FontUtils.apply(tvCurrentTime)
            FontUtils.apply(tvTotalTime)
        }

        setupDrawer()
        setupRecyclerView()
        loadMusicList()
        loadCovers()
        updateDownloadedMusicList()
        initializePlayer()
        // 在加载完音乐列表后恢复播放状态
        restorePlaybackState()
        dislikedMusicIds.addAll(LocalStorage.loadDislikedIds(this))

        // 注册下载完成的广播接收器
        registerReceiver(
            onDownloadComplete,
            IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)
        )

        // 启动时间更新
        startTimeUpdate()

        // 在 onCreate 中添加长按事件
        binding.ivCover.setOnLongClickListener { view ->
            showCoverActionsMenu(view)
            true
        }

        // 添加点击事件监听器，用于随机切换封面
        binding.ivCover.setOnClickListener {
            randomSwitchCover()
        }

        // 请求音频焦点
        requestAudioFocus()
        
        // 强制设置歌词颜色（确保在应用启动时颜色设置正确）
        binding.lrcView.setHighlightColor(Color.WHITE)
        binding.lrcView.setNormalColor(Color.parseColor("#66FFFFFF"))
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        // 处理新的Intent，如果需要的话
        setIntent(intent)
    }

    private fun setupRecyclerView() {
        musicAdapter = MusicAdapter(
            context = this,
            onItemClick = { music ->
                if (FileUtils.isMusicFileExists(this, music)) {
                    playMusic(music)
                }
            },
            onDownloadClick = { music ->
                downloadMusic(music)
            },
            onReDownloadClick = { music ->
                // 先确认是否要重新下载
                MaterialAlertDialogBuilder(this)
                    .setTitle("重新下载")
                    .setMessage("确定要重新下载这首歌吗？")
                    .setNegativeButton("取消", null)
                    .setPositiveButton("确定") { _, _ ->
                        // 删除旧文件
                        FileUtils.getMusicFile(this, music).delete()
                        FileUtils.getLrcFile(this, music).delete()
                        // 开始新的下载
                        downloadMusic(music)
                    }
                    .show()
            },
            onDeleteClick = { music ->
                // 确认是否要删除
                MaterialAlertDialogBuilder(this)
                    .setTitle("删除歌曲")
                    .setMessage("确定要删除这首歌吗？")
                    .setNegativeButton("取消", null)
                    .setPositiveButton("确定") { _, _ ->
                        // 如果正在播放这首歌，先停止播放
                        if (currentMusic?.id == music.id) {
                            player?.stop()
                            currentMusic = null
                            musicAdapter.setPlayingMusic(null)
                        }
                        // 删除文件
                        FileUtils.getMusicFile(this, music).delete()
                        FileUtils.getLrcFile(this, music).delete()
                        // 刷新列表
                        musicAdapter.notifyItemChanged(musicList.indexOf(music))
                        Toast.makeText(this, "删除成功", Toast.LENGTH_SHORT).show()
                    }
                    .show()
            }
        )

        // 设置侧边栏中的列表
        binding.sidebarRecyclerView.apply {
            layoutManager = LinearLayoutManager(this@PlayerActivity)
            adapter = musicAdapter
        }
    }

    private fun loadMusicList() {
        // 从本地加载数据
        LocalStorage.loadPlaylists(this)?.let { response ->
            if (response.code == 0 && response.data.isNotEmpty()) {
                // 保存所有歌单
                allPlaylists = response.data

                // 获取上次使用的歌单ID
                val lastPlaylistId = getSharedPreferences(PREFS_NAME, MODE_PRIVATE)
                    .getInt(KEY_LAST_PLAYLIST_ID, -1)

                // 尝试找到上次使用的歌单，如果没有就使用第一个
                currentPlaylist = if (lastPlaylistId != -1) {
                    allPlaylists.find { it.id == lastPlaylistId } ?: allPlaylists.first()
                } else {
                    allPlaylists.first()
                }

                updatePlaylistDisplay()
                // 选择要播放的歌曲
                selectInitialMusic()
                return
            }
        }

        // 如果本地没有数据，从网络加载
        scope.launch {
            try {
                val response = apiService.getPlaylist()
                if (response.code == 0 && response.data.isNotEmpty()) {
                    allPlaylists = response.data
                    currentPlaylist = allPlaylists.first()
                    LocalStorage.savePlaylists(this@PlayerActivity, response)
                    updatePlaylistDisplay()
                    // 选择要播放的歌曲
                    selectInitialMusic()
                } else {
                    Toast.makeText(
                        this@PlayerActivity,
                        "获取歌单失败: ${response.msg}",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            } catch (e: Exception) {
                Log.e("PlayerActivity", "Error loading playlist", e)
                Toast.makeText(
                    this@PlayerActivity,
                    "获取歌单失败: ${e.message}",
                    Toast.LENGTH_SHORT
                ).show()
            }
        }
    }

    private fun loadCovers() {
        // 从本地加载封面数据
        LocalStorage.loadCovers(this)?.let { response ->
            if (response.code == 0) {
                allCovers = response.data
                Log.d("PlayerActivity", "Loaded ${allCovers.size} covers from local storage")
                
                // 检查每个封面的本地文件状态
                val existingCovers = allCovers.filter { cover ->
                    val file = FileUtils.getCoverFile(this, cover.url)
                    val exists = file.exists()
                    Log.d("PlayerActivity", "Cover ${cover.id} (${cover.name}): file exists = $exists, path = ${file.absolutePath}")
                    exists
                }
                
                Log.d("PlayerActivity", "=== COVER STATISTICS ===")
                Log.d("PlayerActivity", "Total cover info synced: ${allCovers.size}")
                Log.d("PlayerActivity", "Local files found: ${existingCovers.size}")
                Log.d("PlayerActivity", "Missing files: ${allCovers.size - existingCovers.size}")
                
                // 如果有缺失的封面，列出它们
                if (existingCovers.size < allCovers.size) {
                    val missingCovers = allCovers.filter { cover ->
                        !FileUtils.getCoverFile(this, cover.url).exists()
                    }
                    Log.d("PlayerActivity", "Missing cover files:")
                    missingCovers.forEach { cover ->
                        val expectedPath = FileUtils.getCoverFile(this, cover.url).absolutePath
                        Log.d("PlayerActivity", "  - ${cover.name} -> ${expectedPath}")
                    }
                }
                
                Log.d("PlayerActivity", "========================")
            } else {
                Log.d("PlayerActivity", "No covers loaded from local storage (code: ${response.code})")
            }
        } ?: run {
            Log.d("PlayerActivity", "No local covers file found")
        }
    }

    // 新增：根据URL或ID获取封面信息
    private fun getCoverInfo(coverUrl: String): Cover? {
        return allCovers.find { cover ->
            cover.url == coverUrl || coverUrl.contains(cover.name)
        }
    }

    // 新增：获取所有封面信息
    fun getAllCovers(): List<Cover> {
        return allCovers
    }

    private fun selectInitialMusic() {
        // 获取上次播放的歌曲ID
        val lastMusicId = getSharedPreferences(PREFS_NAME, MODE_PRIVATE)
            .getInt(KEY_LAST_MUSIC_ID, -1)

        // 尝试在当前歌单中找到上次播放的歌曲
        val lastMusic = musicList.find { it.id == lastMusicId }

        // 如果找到上次播放的歌曲且已下载，则选择它
        if (lastMusic != null && FileUtils.isMusicFileExists(this, lastMusic)) {
            selectMusic(lastMusic, autoPlay = true)
            return
        }

        // 否则选择当前歌单中第一首已下载的歌曲
        musicList.find { FileUtils.isMusicFileExists(this, it) }?.let {
            selectMusic(it, autoPlay = false)
            return
        }

        // 如果没有已下载的歌曲，只加载第一首歌的信息但不播放
        musicList.firstOrNull()?.let {
            selectMusic(it, autoPlay = false)
        }
    }

    private fun selectMusic(music: Music, autoPlay: Boolean = true) {
        currentMusic = music
        musicAdapter.setPlayingMusic(music)

        // 更新UI
        binding.tvTitle.text = music.name
        binding.tvArtist.text = music.singer

        // 加载封面
        scope.launch {
            try {
                loadCoverImage(music)
            } catch (e: Exception) {
                Log.e("PlayerActivity", "Load cover error", e)
                // 从 assets 加载默认封面
                try {
                    val inputStream = assets.open("default_cover.png")
                    val bitmap = BitmapFactory.decodeStream(inputStream)
                    binding.ivCover.setImageBitmap(bitmap)
                    
                    // 提取默认封面的主题色并应用
                    val themeColors = ColorUtils.extractThemeColors(bitmap)
                    binding.root.setBackgroundColor(themeColors.backgroundColor)
                    binding.sidebarBlurView.setImageBitmap(bitmap)
                    val overlayAlpha = if (ColorUtils.isLightColor(themeColors.backgroundColor)) 0x60 else 0x40
                    binding.sidebarOverlay.setBackgroundColor((overlayAlpha shl 24) or 0x000000)
                    binding.blurView.setImageBitmap(bitmap)
                    updateSeekBarColors(themeColors.accentColor)
                    binding.lrcView.setHighlightColor(themeColors.accentColor)
                    binding.lrcView.setNormalColor(Color.parseColor("#66FFFFFF"))
                } catch (e: Exception) {
                    Log.e("PlayerActivity", "Load default cover error", e)
                }
            }
        }

        // 加载歌词
        val lrcFile = FileUtils.getLrcFile(this, music)
        if (lrcFile.exists()) {
            try {
                // 读取歌词文件内容
                val lrcContent = lrcFile.readText()
                val lyricLines = parseLyrics(lrcContent)
                binding.lrcView.updateLyrics(lyricLines)  // 假设 LyricsView 继承自 TextView
            } catch (e: Exception) {
                Log.e("PlayerActivity", "Load lyrics error", e)
                binding.lrcView.updateLyrics(listOf(LyricLine(0, "暂无歌词")))
            }
        } else {
            binding.lrcView.updateLyrics(listOf(LyricLine(0, "暂无歌词")))
        }

        // 准备播放器
        val musicFile = FileUtils.getMusicFile(this, music)
        player?.apply {
            setMediaItem(MediaItem.fromUri(musicFile.toUri()))
            prepare()
            if (autoPlay) {
                play()
            }
        }

        // 更新播放/暂停按钮图标
        updatePlayPauseButton()
    }

    private fun updatePlayPauseButton() {
        val isPlaying = player?.isPlaying == true
        binding.btnPlayPause.setImageResource(
            if (isPlaying) android.R.drawable.ic_media_pause
            else android.R.drawable.ic_media_play
        )
    }

    private fun updatePlaylistDisplay() {
        currentPlaylist?.let { playlist ->
            // 保存当前歌单ID
            getSharedPreferences(PREFS_NAME, MODE_PRIVATE)
                .edit()
                .putInt(KEY_LAST_PLAYLIST_ID, playlist.id)
                .apply()

            // 更新歌曲列表
            musicList = playlist.musics
            musicAdapter.updateList(musicList)

            // 更新已下载列表
            updateDownloadedMusicList()

            // 如果当前播放的歌曲不在新歌单中，停止播放并选择新歌单中的歌曲
            if (currentMusic != null && !musicList.contains(currentMusic)) {
                player?.stop()
                currentMusic = null
                updatePlayPauseState(false)
                selectInitialMusic()
            }
        }
        
        // 更新歌单标签
        updatePlaylistTabs()
    }

    private fun updatePlaylistTabs() {
        // 清除现有标签
        binding.playlistTabsContainer.removeAllViews()
        playlistTabs.clear()

        // 为每个歌单创建标签
        allPlaylists.forEachIndexed { index, playlist ->
            val tabView = TextView(this).apply {
                text = playlist.name
                textSize = 16f
                val isCurrentPlaylist = playlist.id == currentPlaylist?.id
                setTextColor(if (isCurrentPlaylist) Color.WHITE else Color.parseColor("#CCFFFFFF"))
                background = ColorDrawable(if (isCurrentPlaylist) Color.parseColor("#40FFFFFF") else Color.parseColor("#20FFFFFF"))
                setPadding(16, 12, 16, 12)
                isSelected = isCurrentPlaylist
                
                // 应用自定义字体
                FontUtils.apply(this)
                
                // 添加点击事件
                setOnClickListener {
                    switchToPlaylist(playlist)
                }

                // 设置布局参数
                val params = android.view.ViewGroup.MarginLayoutParams(
                    android.view.ViewGroup.LayoutParams.WRAP_CONTENT,
                    android.view.ViewGroup.LayoutParams.WRAP_CONTENT
                ).apply {
                    marginEnd = 12
                }
                layoutParams = params
            }
            
            binding.playlistTabsContainer.addView(tabView)
            playlistTabs.add(tabView)
        }
    }

    private fun switchToPlaylist(playlist: Playlist) {
        if (playlist.id == currentPlaylist?.id) return
        
        clearPlayHistory()  // 清除播放历史
        currentPlaylist = playlist
        
        // 重置上次使用的封面ID，确保新歌单能重新随机选择封面
        lastUsedCoverId = null

        // 更新歌单标签选中状态和颜色
        playlistTabs.forEachIndexed { index, tabView ->
            val isSelected = allPlaylists[index].id == playlist.id
            tabView.isSelected = isSelected
            tabView.setTextColor(if (isSelected) Color.WHITE else Color.parseColor("#CCFFFFFF"))
            tabView.background = ColorDrawable(if (isSelected) Color.parseColor("#40FFFFFF") else Color.parseColor("#20FFFFFF"))
        }

        // 更新歌单显示
        updatePlaylistDisplay()

        // 更新已下载列表
        updateDownloadedMusicList()

        // 如果当前播放的歌曲不在新歌单中，停止播放
        if (currentMusic != null && !playlist.musics.contains(currentMusic)) {
            player?.stop()
            currentMusic = null
            updatePlayPauseState(false)
        }

        // 保存当前歌单ID
        getSharedPreferences(PREFS_NAME, MODE_PRIVATE)
            .edit()
            .putInt(KEY_LAST_PLAYLIST_ID, playlist.id)
            .apply()
    }

    private fun initializePlayer() {
        player = ExoPlayer.Builder(this)
            .build().apply {
                addListener(playerListener)
            }

        // 设置播放控制
        binding.apply {
            btnPlayPause.setOnClickListener {
                if (player?.isPlaying == true) {
                    player?.pause()
                    updatePlayPauseState(false)
                } else {
                    if (isGlobalShuffleMode && currentMusic == null) {
                        startGlobalShuffleIfIdle()
                    } else {
                        player?.play()
                    }
                    updatePlayPauseState(true)
                }
            }

            btnPrevious.setOnClickListener { playPreviousSong() }
            btnNext.setOnClickListener { playNextSong() }

            seekBar.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
                override fun onProgressChanged(
                    seekBar: SeekBar?,
                    progress: Int,
                    fromUser: Boolean
                ) {
                    if (fromUser) {
                        player?.seekTo((progress * 1000).toLong())
                    }
                }

                override fun onStartTrackingTouch(seekBar: SeekBar?) {}
                override fun onStopTrackingTouch(seekBar: SeekBar?) {}
            })
        }

        // 更新进度条
        scope.launch {
            while (true) {
                delay(200)  // 减小更新间隔到200ms
                updateProgress()
            }
        }

        // 设置播放模式按钮点击事件
        binding.btnPlayMode.setOnClickListener {
            currentPlayMode = when (currentPlayMode) {
                PlayMode.SEQUENCE -> PlayMode.REPEAT_ONE
                PlayMode.REPEAT_ONE -> PlayMode.SEQUENCE
                PlayMode.SHUFFLE -> PlayMode.SEQUENCE
            }
            updatePlayModeUI()
            savePlayModePrefs()
        }

        // 设置随机播放按钮点击事件
        binding.btnShuffle.setOnClickListener {
            isShuffleEnabled = !isShuffleEnabled
            currentPlayMode = if (isShuffleEnabled) PlayMode.SHUFFLE else PlayMode.SEQUENCE
            updatePlayModeUI()
            savePlayModePrefs()
            if (isShuffleEnabled) shuffleOrder = mutableListOf<Int>().apply {
                val curIdx = downloadedMusicList.indexOf(currentMusic)
                addAll(downloadedMusicList.indices.filter { it != curIdx })
                shuffle()
            } else shuffleOrder.clear()
        }

        binding.btnGlobalShuffle.setOnClickListener {
            enterGlobalShuffleMode()
        }

        binding.btnExitGlobalShuffle.setOnClickListener {
            exitGlobalShuffleMode()
        }

        binding.btnDislike.setOnClickListener {
            currentMusic?.let { m ->
                dislikedMusicIds.add(m.id)
                LocalStorage.saveDislikedIds(this@PlayerActivity, dislikedMusicIds.toList())
                if (isGlobalShuffleMode) {
                    rebuildGlobalQueue()
                    updateNextUpLabel()
                }
                playNextSong()
            }
        }

        binding.btnViewDislikes.setOnClickListener {
            showDislikedDrawer()
        }
    }

    private val playerListener = object : Player.Listener {
        override fun onPlaybackStateChanged(playbackState: Int) {
            when (playbackState) {
                Player.STATE_ENDED -> {
                    playNextSong()
                }

                Player.STATE_READY -> {
                    // 如果是从暂停恢复播放，也使用渐入效果
                    if (player?.isPlaying == true) {
                        startVolumeAnimation()
                    }
                    savePlaybackState()
                }

                Player.STATE_BUFFERING -> {
                    // 如果播放器正在缓冲，则使用淡入淡出效果
                    if (player?.isPlaying == true) {
                        startVolumeAnimation()
                    }
                }

                else -> {
                    // 其他状态，不做任何操作
                }
            }
        }

        override fun onIsPlayingChanged(isPlaying: Boolean) {
            updatePlayPauseState(isPlaying)
            if (!isPlaying) {
                savePlaybackState()
            }
        }

        override fun onPlayerError(error: PlaybackException) {
            Log.e("PlayerActivity", "Playback error", error)
            Toast.makeText(
                this@PlayerActivity,
                "播放出错: ${error.message}",
                Toast.LENGTH_SHORT
            ).show()
        }
    }

    private fun playMusic(music: Music, addToHistory: Boolean = true) {
        try {
            if (addToHistory) {
                addToHistory(music)
            }

            // 更新当前播放的音乐
            currentMusic = music
            musicAdapter.setPlayingMusic(music)
            
            // 检查歌曲是否有可用的封面，如果没有，重置上次使用的封面ID以确保随机选择
            val hasMusicCover = music.covers?.isNotEmpty() == true && 
                FileUtils.getCoverFile(this, music.covers.split(",").firstOrNull() ?: "").exists()
            
            if (!hasMusicCover) {
                lastUsedCoverId = null
                Log.d("PlayerActivity", "Song has no cover, reset lastUsedCoverId for random selection: ${music.name}")
            } else {
                Log.d("PlayerActivity", "Song has cover, keeping lastUsedCoverId: ${music.name}")
            }

            // 更新界面显示
            binding.tvTitle.text = music.name
            binding.tvArtist.text = music.singer

            // 加载封面
            scope.launch {
                loadCoverImage(music)
            }

            // 加载歌词
            loadLyrics(music)

            // 准备播放器
            val musicFile = FileUtils.getMusicFile(this, music)
            player?.apply {
                // 先将音量设为0
                volume = 0f
                setMediaItem(MediaItem.fromUri(musicFile.toUri()))
                prepare()
                play()

                // 开始音量渐入动画
                startVolumeAnimation()
            }

            savePlaybackState()
            updateNextUpLabel()

        } catch (e: Exception) {
            Log.e("PlayerActivity", "Error playing music", e)
            Toast.makeText(this, "播放失败: ${e.message}", Toast.LENGTH_SHORT).show()
        }
    }

    private fun loadLyrics(music: Music) {
        val lrcFile = FileUtils.getLrcFile(this, music)
        if (lrcFile.exists()) {
            try {
                val lyrics = lrcFile.readText()
                // 解析歌词
                val lyricLines = parseLyrics(lyrics)
                binding.lrcView.updateLyrics(lyricLines)
            } catch (e: Exception) {
                Log.e("PlayerActivity", "Error loading lyrics", e)
                binding.lrcView.updateLyrics(listOf(LyricLine(0, "暂无歌词")))
            }
        } else {
            binding.lrcView.updateLyrics(listOf(LyricLine(0, "暂无歌词")))
        }
    }

    private fun parseLyrics(lrcText: String): List<LyricLine> {
        val lines = lrcText.split("\n").map { it.trim() }
        val timeRegex = "\\[(\\d{2}):(\\d{2})\\.(\\d{1,3})](.*)".toRegex()
        // 提前显示歌词，让用户提前知道下面的歌词
        val advancedTimestamp = 200
        return lines.mapNotNull { line ->
            timeRegex.matchEntire(line)?.let { matchResult ->
                val (min, sec, ms, text) = matchResult.destructured
                val timestamp = (min.toLong() * 60 * 1000) +
                        (sec.toLong() * 1000) +
                        (ms.padEnd(3, '0').toLong()) - advancedTimestamp
                LyricLine(timestamp, text.trim())
            }
        }.sortedBy { it.timestamp }
    }

    private fun updateProgress() {
        player?.let { player ->
            val duration = player.duration
            val currentPosition = player.currentPosition
            if (duration > 0) {
                binding.seekBar.max = (duration / 1000).toInt()
                binding.seekBar.progress = (currentPosition / 1000).toInt()
                binding.tvCurrentTime.text = formatTime(currentPosition)
                binding.tvTotalTime.text = formatTime(duration)
                if (player.isPlaying) {
                    binding.lrcView.updatePosition(currentPosition)
                }
            }
        }
    }

    private fun formatTime(timeMs: Long): String {
        val totalSeconds = timeMs / 1000
        val minutes = totalSeconds / 60
        val seconds = totalSeconds % 60
        return String.format(Locale.getDefault(), "%02d:%02d", minutes, seconds)
    }

    private fun playNextSong() {
        if (isGlobalShuffleMode && currentMusic == null) {
            val first = getNextGlobalShuffleSong()
            if (first != null) {
                playMusic(first)
                updateNextUpLabel()
            } else {
                Toast.makeText(this, "没有可播放的歌曲", Toast.LENGTH_SHORT).show()
            }
            return
        }
        currentMusic?.let { current ->
            val nextSong = getNextPlayableSong(current)
            if (nextSong != null) {
                playMusic(nextSong)
                updateNextUpLabel()
            } else {
                Toast.makeText(this, "没有可播放的歌曲", Toast.LENGTH_SHORT).show()
            }
        }
    }

    private fun playPreviousSong() {
        when {
            // 如果播放时间超过3秒，重新播放当前歌曲
            (player?.currentPosition ?: 0) > 3000 -> {
                player?.seekTo(0)
                player?.play()
            }
            // 如果有播放历史，播放上一首
            historyIndex > 0 -> {
                historyIndex--
                val previousMusic = playHistory[historyIndex]
                if (FileUtils.isMusicFileExists(this, previousMusic)) {
                    playMusic(previousMusic, addToHistory = false)
                } else {
                    // 如果文件不存在，继续往前找
                    playPreviousSong()
                }
            }
            // 如果是随机播放模式且没有历史，随机选择一首
            currentPlayMode == PlayMode.SHUFFLE -> {
                getRandomPlayableSong()?.let { music ->
                    playMusic(music)
                }
            }
            // 顺序播放模式，播放列表中的上一首
            else -> {
                currentMusic?.let { current ->
                    val currentIndex = downloadedMusicList.indexOf(current)
                    if (currentIndex > 0) {
                        playMusic(downloadedMusicList[currentIndex - 1])
                    } else if (downloadedMusicList.isNotEmpty()) {
                        // 循环到最后一首
                        playMusic(downloadedMusicList.last())
                    } else {

                    }
                }
            }
        }
    }

    private fun downloadMusic(music: Music) {
        scope.launch {
            try {
                val success = FileDownloader.downloadFile(
                    context = this@PlayerActivity,
                    music = music,
                    onProgress = { progress ->
                        musicAdapter.updateDownloadProgress(music.id, progress)
                    }
                )

                if (success) {
                    musicAdapter.setDownloading(music.id, false)
                    musicAdapter.updateList(musicList)
                    updateDownloadedMusicList()  // 下载完成后更新已下载列表
                    onMusicDownloadComplete(music)  // 调用下载完成处理
                    Toast.makeText(this@PlayerActivity, "下载成功", Toast.LENGTH_SHORT).show()
                } else {
                    musicAdapter.setDownloading(music.id, false)
                    Toast.makeText(this@PlayerActivity, "下载失败", Toast.LENGTH_SHORT).show()
                }
            } catch (e: Exception) {
                Log.e("PlayerActivity", "Download error", e)
                musicAdapter.setDownloading(music.id, false)
                Toast.makeText(this@PlayerActivity, "下载出错: ${e.message}", Toast.LENGTH_SHORT)
                    .show()
            }
        }
    }

    private fun setupDrawer() {
        // 初始化抽屉监听器
        drawerListener = object : DrawerLayout.DrawerListener {
            override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}
            override fun onDrawerOpened(drawerView: View) {
                Log.d("PlayerActivity", "Drawer opened: ${drawerView == settingsDrawerView}")
            }
            override fun onDrawerStateChanged(newState: Int) {
                Log.d("PlayerActivity", "Drawer state changed: $newState")
            }
            
            override fun onDrawerClosed(drawerView: View) {
                Log.d("PlayerActivity", "Drawer closed: ${drawerView == settingsDrawerView}")
                if (drawerView == settingsDrawerView && !isCreatingSettingsDrawer) {
                    binding.drawerLayout.removeView(settingsDrawerView)
                    settingsDrawerView = null
                }
                if (drawerView == dislikedDrawerView) {
                    binding.drawerLayout.removeView(dislikedDrawerView)
                    dislikedDrawerView = null
                }
            }
        }
        
        // 添加监听器
        binding.drawerLayout.addDrawerListener(drawerListener!!)

        // 侧边栏收起按钮点击事件
        binding.btnCollapseSidebar.setOnClickListener {
            toggleSidebar()
        }

        // 显示歌单按钮点击事件（当侧边栏隐藏时显示）
        binding.showPlaylist.setOnClickListener {
            toggleSidebar()
        }

        // 设置按钮点击事件
        binding.btnSettings.setOnClickListener {
            showSettingsDrawer()
        }
    }

    private fun showSettingsDrawer() {
        // 如果设置抽屉已经存在，直接打开
        if (settingsDrawerView != null) {
            Log.d("PlayerActivity", "Settings drawer already exists, opening...")
            binding.drawerLayout.openDrawer(GravityCompat.END)
            return
        }

        // 如果正在创建设置抽屉，避免重复创建
        if (isCreatingSettingsDrawer) {
            Log.d("PlayerActivity", "Settings drawer is already being created")
            return
        }

        try {
            isCreatingSettingsDrawer = true
            Log.d("PlayerActivity", "Creating new settings drawer...")
            
            // 创建设置抽屉视图
            settingsDrawerView = layoutInflater.inflate(R.layout.layout_settings_drawer, null)
            
            // 设置布局参数
            val layoutParams = DrawerLayout.LayoutParams(
                320.dpToPx(this),
                DrawerLayout.LayoutParams.MATCH_PARENT,
                GravityCompat.END
            )
            settingsDrawerView!!.layoutParams = layoutParams
            
            // 添加到 DrawerLayout
            binding.drawerLayout.addView(settingsDrawerView)
            
            // 设置点击事件
            setupSettingsDrawerEvents(settingsDrawerView!!)
            updateStorageInfo(settingsDrawerView!!)
            
            // 使用 post 延迟打开抽屉，确保视图已经添加完成
            binding.drawerLayout.post {
                isCreatingSettingsDrawer = false
                Log.d("PlayerActivity", "Opening settings drawer...")
                binding.drawerLayout.openDrawer(GravityCompat.END)
            }
            
        } catch (e: Exception) {
            isCreatingSettingsDrawer = false
            Log.e("PlayerActivity", "Error creating settings drawer", e)
            Toast.makeText(this, "设置面板打开失败", Toast.LENGTH_SHORT).show()
        }
    }

    private fun toggleSidebar() {
        isSidebarVisible = !isSidebarVisible
        
        if (isSidebarVisible) {
            // 显示侧边栏
            binding.sidebarContainer.visibility = View.VISIBLE
            binding.showPlaylist.visibility = View.GONE
            
            // 添加显示动画
            binding.sidebarContainer.alpha = 0f
            binding.sidebarContainer.animate()
                .alpha(1f)
                .setDuration(300)
                .start()
        } else {
            // 隐藏侧边栏
            binding.showPlaylist.visibility = View.VISIBLE
            
            // 添加隐藏动画
            binding.sidebarContainer.animate()
                .alpha(0f)
                .setDuration(300)
                .withEndAction {
                    binding.sidebarContainer.visibility = View.GONE
                }
                .start()
        }
    }

    private fun showDislikedDrawer() {
        if (dislikedDrawerView != null) {
            binding.drawerLayout.openDrawer(GravityCompat.END)
            return
        }
        try {
            val view = layoutInflater.inflate(R.layout.layout_disliked_drawer, null)
            val params = DrawerLayout.LayoutParams(
                320.dpToPx(this),
                DrawerLayout.LayoutParams.MATCH_PARENT,
                GravityCompat.END
            )
            view.layoutParams = params
            binding.drawerLayout.addView(view)
            dislikedDrawerView = view

            val recycler = view.findViewById<androidx.recyclerview.widget.RecyclerView>(R.id.rvDisliked)
            recycler.layoutManager = androidx.recyclerview.widget.LinearLayoutManager(this)
            val adapter = DislikedAdapter(this) { music ->
                dislikedMusicIds.remove(music.id)
                LocalStorage.saveDislikedIds(this, dislikedMusicIds.toList())
                if (isGlobalShuffleMode) {
                    rebuildGlobalQueue()
                    updateNextUpLabel()
                }
                val currentAll = allPlaylists.flatMap { it.musics }.distinctBy { it.id }
                val curList = currentAll.filter { dislikedMusicIds.contains(it.id) }
                (recycler.adapter as? DislikedAdapter)?.updateList(curList)
            }
            recycler.adapter = adapter

            val allMusics = allPlaylists.flatMap { it.musics }.distinctBy { it.id }
            val dislikedList = allMusics.filter { dislikedMusicIds.contains(it.id) }
            adapter.updateList(dislikedList)

            view.findViewById<View>(R.id.btnCloseDisliked).setOnClickListener {
                binding.drawerLayout.closeDrawer(GravityCompat.END)
            }

            binding.drawerLayout.post {
                binding.drawerLayout.openDrawer(GravityCompat.END)
            }
        } catch (e: Exception) {
            Toast.makeText(this, "不喜欢列表打开失败", Toast.LENGTH_SHORT).show()
        }
    }

    private fun setupSettingsDrawerEvents(settingsView: View) {
        // 关闭按钮点击事件
        settingsView.findViewById<View>(R.id.btnCloseSettings).setOnClickListener {
            binding.drawerLayout.closeDrawer(GravityCompat.END)
        }

        // 同步歌单
        settingsView.findViewById<View>(R.id.btnSyncPlaylist).setOnClickListener {
            syncPlaylist()
            binding.drawerLayout.closeDrawer(GravityCompat.END)
        }

        // 同步封面库
        settingsView.findViewById<View>(R.id.btnSyncCovers).setOnClickListener {
            checkAndSyncCovers()
            binding.drawerLayout.closeDrawer(GravityCompat.END)
        }

        // 检查更新
        settingsView.findViewById<View>(R.id.btnCheckUpdate).setOnClickListener {
            checkUpdate()
            binding.drawerLayout.closeDrawer(GravityCompat.END)
        }

        // 关于
        settingsView.findViewById<View>(R.id.btnAbout).setOnClickListener {
            showAboutDialog()
            binding.drawerLayout.closeDrawer(GravityCompat.END)
        }

        // 退出登录
        settingsView.findViewById<View>(R.id.btnLogout).setOnClickListener {
            showLogoutConfirmationDialog()
            binding.drawerLayout.closeDrawer(GravityCompat.END)
        }

        updateStorageInfo(settingsView)
    }

    private fun updateStorageInfo(settingsView: View) {
        val totalView = settingsView.findViewById<TextView>(R.id.tvStorageTotalValue)
        val freeView = settingsView.findViewById<TextView>(R.id.tvStorageFreeValue)
        val appView = settingsView.findViewById<TextView>(R.id.tvStorageSongValue)
        val segSong = settingsView.findViewById<View>(R.id.storageSegmentSong)
        val segUsedOther = settingsView.findViewById<View>(R.id.storageSegmentUsedOther)
        val segFree = settingsView.findViewById<View>(R.id.storageSegmentFree)

        val dir = getExternalFilesDir(null)
        val stat = dir?.let { StatFs(it.absolutePath) }
        val total = stat?.let { it.blockSizeLong * it.blockCountLong } ?: 0L
        val available = stat?.let { it.blockSizeLong * it.availableBlocksLong } ?: 0L
        val used = (total - available).coerceAtLeast(0L)
        val appDir = File(dir, "music")
        val appSize = folderSize(appDir)
        val usedOther = (used - appSize).coerceAtLeast(0L)

        totalView.text = formatSize(total)
        freeView.text = formatSize(available)
        appView.text = formatSize(appSize)

        val sum = (appSize + usedOther + available).takeIf { it > 0 } ?: 1L
        val appPct = (appSize * 100f / sum)
        val usedPct = (usedOther * 100f / sum)
        val freePct = (available * 100f / sum)

        (segSong.layoutParams as? android.widget.LinearLayout.LayoutParams)?.let {
            it.width = 0
            it.weight = appPct
            segSong.layoutParams = it
        }
        (segUsedOther.layoutParams as? android.widget.LinearLayout.LayoutParams)?.let {
            it.width = 0
            it.weight = usedPct
            segUsedOther.layoutParams = it
        }
        (segFree.layoutParams as? android.widget.LinearLayout.LayoutParams)?.let {
            it.width = 0
            it.weight = freePct
            segFree.layoutParams = it
        }
    }

    private fun formatSize(bytes: Long): String {
        val kb = 1024L
        val mb = kb * 1024
        val gb = mb * 1024
        return when {
            bytes >= gb -> String.format(Locale.getDefault(), "%.2f GB", bytes.toDouble() / gb)
            bytes >= mb -> String.format(Locale.getDefault(), "%.2f MB", bytes.toDouble() / mb)
            bytes >= kb -> String.format(Locale.getDefault(), "%.2f KB", bytes.toDouble() / kb)
            else -> "$bytes B"
        }
    }

    private fun folderSize(dir: File?): Long {
        if (dir == null || !dir.exists()) return 0L
        var size = 0L
        val files = dir.listFiles() ?: return 0L
        for (f in files) {
            size += if (f.isFile) f.length() else folderSize(f)
        }
        return size
    }

    private fun checkAndSyncCovers() {
        scope.launch {
            try {
                // 显示加载提示
                withContext(Dispatchers.Main) {
                    showLoadingDialog("正在检查封面库...")
                }

                // 获取远程封面库信息
                val response = apiService.getCovers()
                
                // 隐藏加载提示
                withContext(Dispatchers.Main) {
                    dismissLoadingDialog()
                }
                
                if (response.code == 0) {
                    val remoteCovers = response.data
                    val localCovers = allCovers

                    // 比较本地和远程封面库
                    val newCovers = remoteCovers.filter { remote ->
                        localCovers.none { local -> local.id == remote.id }
                    }

                    if (newCovers.isNotEmpty()) {
                        // 显示确认对话框
                        withContext(Dispatchers.Main) {
                            MaterialAlertDialogBuilder(this@PlayerActivity, R.style.CustomAlertDialog)
                                .setTitle("发现新封面")
                                .setMessage("发现 ${newCovers.size} 个新封面资源，是否立即下载？")
                                .setNegativeButton("稍后再说", null)
                                .setPositiveButton("立即下载") { _, _ ->
                                    // 保存新的封面信息
                                    allCovers = remoteCovers
                                    LocalStorage.saveCovers(this@PlayerActivity, response)
                                    // 开始下载新封面
                                    downloadNewCovers(newCovers)
                                }
                                .show()
                        }
                    } else {
                        withContext(Dispatchers.Main) {
                            Toast.makeText(this@PlayerActivity, "封面库已是最新", Toast.LENGTH_SHORT).show()
                        }
                    }
                } else {
                    withContext(Dispatchers.Main) {
                        Toast.makeText(this@PlayerActivity, "检查失败: ${response.msg}", Toast.LENGTH_SHORT).show()
                    }
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    dismissLoadingDialog()
                    Toast.makeText(this@PlayerActivity, "检查失败: ${e.message}", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }

    private fun showLoadingDialog(message: String) {
        // 先关闭之前的对话框
        dismissLoadingDialog()
        
        loadingDialog = MaterialAlertDialogBuilder(this, R.style.CustomAlertDialog)
            .setView(layoutInflater.inflate(R.layout.dialog_loading, null).apply {
                findViewById<TextView>(R.id.loadingMessage).text = message
            })
            .setCancelable(false)
            .create()
        
        loadingDialog?.show()
    }

    private fun dismissLoadingDialog() {
        loadingDialog?.let { dialog ->
            if (dialog.isShowing) {
                dialog.dismiss()
            }
        }
        loadingDialog = null
    }

    // 扩展函数：dp 转 px
    private fun Int.dpToPx(context: Context): Int {
        return (this * context.resources.displayMetrics.density).toInt()
    }

    private fun showAboutDialog() {
        // 实现显示关于对话框的逻辑
    }

    private fun showLogoutConfirmationDialog() {
        MaterialAlertDialogBuilder(this)
            .setTitle("退出登录")
            .setMessage("确定要退出登录吗？退出后将无法使用需要登录的功能。")
            .setNegativeButton("取消", null)
            .setPositiveButton("确定") { _, _ ->
                performLogout()
            }
            .show()
    }

    private fun performLogout() {
        // 使用AuthManager退出登录
        xin.ryven.car.android.utils.AuthManager.logout(this)
        
        // 显示退出成功提示
        Toast.makeText(this, "已退出登录", Toast.LENGTH_SHORT).show()
        
        // 停止当前播放
        player?.pause()
        updatePlayPauseState(false)
        
        // 可以选择清空当前播放列表或进行其他清理操作
        // 注意：根据应用逻辑，可能需要重新加载歌单或显示登录界面
    }

    private fun updateDownloadedMusicList() {
        downloadedMusicList.clear()
        downloadedMusicList.addAll(musicList.filter { music ->
            FileUtils.isMusicFileExists(this, music)
        })
        if (isShuffleEnabled) {
            shuffleOrder.clear()
            val curIdx = downloadedMusicList.indexOf(currentMusic)
            shuffleOrder.addAll(downloadedMusicList.indices.filter { it != curIdx })
            shuffleOrder.shuffle()
        }
    }

    private fun onMusicDownloadComplete(music: Music) {
        if (!downloadedMusicList.contains(music)) {
            downloadedMusicList.add(music)
            // 如果是第一首下载的歌曲，自动开始播放
            if (downloadedMusicList.size == 1 && player?.isPlaying != true) {
                playMusic(music)
            }
        }
    }

    private fun addToHistory(music: Music) {
        // 如果不是从历史记录中播放，则清除当前位置之后的历史
        if (historyIndex < playHistory.size - 1) {
            playHistory.subList(historyIndex + 1, playHistory.size).clear()
        }

        // 添加新的记录
        playHistory.add(music)
        historyIndex = playHistory.size - 1

        // 如果历史记录太长，删除最早的记录
        if (playHistory.size > maxHistorySize) {
            playHistory.removeFirst()
            historyIndex--
        }
    }

    private fun clearPlayHistory() {
        playHistory.clear()
        historyIndex = -1
    }

    private fun showCoverActionsMenu(view: View) {
        PopupMenu(this, view).apply {
            menuInflater.inflate(R.menu.menu_cover_actions, menu)
            setOnMenuItemClickListener { item ->
                when (item.itemId) {
                    R.id.action_update_cover_lyrics -> {
                        currentMusic?.let { music ->
                            updateCoverAndLyrics(music)
                        }
                        true
                    }

                    else -> false
                }
            }
            show()
        }
    }

    private fun updateCoverAndLyrics(music: Music) {
        scope.launch {
            try {
                var success = true

                // 更新进度提示
                withContext(Dispatchers.Main) {
                    Toast.makeText(this@PlayerActivity, "开始更新封面和歌词...", Toast.LENGTH_SHORT)
                        .show()
                }

                // 下载歌词
                if (!music.lrcUrl.isNullOrEmpty()) {
                    val lrcFile = FileUtils.getLrcFile(this@PlayerActivity, music)
                    success =
                        success && FileDownloader.downloadFile(music.lrcUrl, lrcFile) { progress ->
                            // 可以在这里更新进度，如果需要的话
                        }
                }

                // 下载封面
                if (!music.covers.isNullOrEmpty()) {
                    val coverFile = FileUtils.getCoverFile(
                        this@PlayerActivity,
                        music.covers.split(",").firstOrNull() ?: ""
                    )
                    success = success && FileDownloader.downloadFile(
                        music.covers,
                        coverFile
                    ) { progress ->
                        // 可以在这里更新进度，如果需要的话
                    }

                    // 如果是当前播放的歌曲，更新界面显示
                    if (success && music.id == currentMusic?.id) {
                        withContext(Dispatchers.Main) {
                            updateCoverImage(music)
                            loadLyrics(music)  // 重新加载歌词
                        }
                    }
                }

                // 显示结果
                withContext(Dispatchers.Main) {
                    Toast.makeText(
                        this@PlayerActivity,
                        if (success) "更新成功" else "更新失败",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            } catch (e: Exception) {
                withContext(Dispatchers.Main) {
                    Toast.makeText(
                        this@PlayerActivity,
                        "更新失败: ${e.message}",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            }
        }
    }

    private fun updateCoverImage(music: Music) {
        scope.launch {
        try {
                val bitmap = withContext(Dispatchers.IO) {
                    when {
                        // 1. 如果歌曲有封面，优先使用歌曲的封面
                        music.covers?.isNotEmpty() == true -> {
                            val coverFile = FileUtils.getCoverFile(
                                this@PlayerActivity,
                                music.covers.split(",").firstOrNull() ?: ""
                            )
                            if (coverFile.exists()) {
                                Log.d("PlayerActivity", "Using music cover file: ${coverFile.name}")
                                BitmapFactory.decodeFile(coverFile.absolutePath)
                            } else {
                                Log.d("PlayerActivity", "Music cover file not found, trying cached covers")
                                // 歌曲封面文件不存在，尝试使用缓存的封面
                                getRandomCachedCoverBitmap() ?: run {
                                    Log.d("PlayerActivity", "No cached covers available, using default")
                                    // 如果没有缓存封面，使用默认封面
                                    assets.open("bg/default_cover.png")
                                        .use { BitmapFactory.decodeStream(it) }
                                }
                            }
                        }
                        
                        // 2. 如果歌曲没有封面，从本地缓存的封面列表中随机获取一个
                        allCovers.isNotEmpty() -> {
                            Log.d("PlayerActivity", "Music has no covers, using random cached cover")
                            getRandomCachedCoverBitmap() ?: run {
                                Log.d("PlayerActivity", "Failed to get random cached cover, using default")
                                // 如果随机获取失败，使用默认封面
                                assets.open("bg/default_cover.png")
                                    .use { BitmapFactory.decodeStream(it) }
                            }
                        }

                        // 3. 如果本地没有封面或者封面数量是0，使用默认封面
                        else -> {
                            Log.d("PlayerActivity", "No cached covers available, using default cover")
                            assets.open("bg/default_cover.png")
                                .use { BitmapFactory.decodeStream(it) }
                        }
                    }
                }

                // 提取主题颜色
                val themeColors = ColorUtils.extractThemeColors(bitmap)

                withContext(Dispatchers.Main) {
                    // 更新封面图片
                    binding.ivCover.setImageBitmap(bitmap)

                    // 更新背景颜色
                    binding.root.setBackgroundColor(themeColors.backgroundColor)
                    
                    // 更新侧边栏毛玻璃效果
                    binding.sidebarBlurView.setImageBitmap(bitmap)
                    // 根据主题色调整侧边栏遮罩透明度
                    val overlayAlpha = if (ColorUtils.isLightColor(themeColors.backgroundColor)) 0x60 else 0x40
                    binding.sidebarOverlay.setBackgroundColor((overlayAlpha shl 24) or 0x000000)
                    binding.blurView.setImageBitmap(bitmap)
                    updateSeekBarColors(themeColors.accentColor)
                    binding.lrcView.setHighlightColor(themeColors.accentColor)
                    binding.lrcView.setNormalColor(Color.parseColor("#66FFFFFF"))
                }
            } catch (e: Exception) {
                Log.e("PlayerActivity", "Error loading cover image", e)
                // 出错时使用默认封面
                withContext(Dispatchers.Main) {
                    try {
                        val defaultBitmap = assets.open("bg/default_cover.png").use { BitmapFactory.decodeStream(it) }
                        binding.ivCover.setImageBitmap(defaultBitmap)
                        binding.blurView.setImageBitmap(defaultBitmap)
                        
                        // 更新侧边栏毛玻璃背景
                        binding.sidebarBlurView.setImageBitmap(defaultBitmap)
                        
                        // 提取默认封面的主题色并应用
                        val colors = ColorUtils.extractThemeColors(defaultBitmap)
                        updateThemeColors(colors.backgroundColor, colors.accentColor)
                    } catch (e2: Exception) {
                        Log.e("PlayerActivity", "Error loading default cover in updateCoverImage", e2)
                    }
                }
            }
        }
    }

    private fun updateThemeColors(backgroundColor: Int, accentColor: Int) {
        // 更新背景色
        binding.root.setBackgroundColor(backgroundColor)
        
        // 更新侧边栏遮罩透明度
        val overlayAlpha = if (ColorUtils.isLightColor(backgroundColor)) 0x60 else 0x40
        binding.sidebarOverlay.setBackgroundColor((overlayAlpha shl 24) or 0x000000)

        // 更新歌词颜色
        binding.lrcView.setHighlightColor(accentColor) // 高亮歌词颜色
        binding.lrcView.setNormalColor(Color.parseColor("#66FFFFFF")) // 普通歌词使用更灰的白色

        // 更新进度条颜色
        binding.seekBar.progressTintList = ColorStateList.valueOf(accentColor)
        binding.seekBar.thumbTintList = ColorStateList.valueOf(accentColor)
    }

    private fun getNextPlayableSong(current: Music): Music? {
        if (isGlobalShuffleMode) {
            return getNextGlobalShuffleSong()
        }
        return when (currentPlayMode) {
            PlayMode.SEQUENCE -> getNextSequentialPlayableSong(current)
            PlayMode.REPEAT_ONE -> current
            PlayMode.SHUFFLE -> getNextShuffleSong()
        }
    }

    private fun getNextSequentialPlayableSong(current: Music): Music? {
        if (downloadedMusicList.isEmpty()) return null

        val currentIndex = downloadedMusicList.indexOf(current)
        return when {
            currentIndex == -1 -> downloadedMusicList.firstOrNull()
            currentIndex < downloadedMusicList.size - 1 -> downloadedMusicList[currentIndex + 1]
            else -> downloadedMusicList.firstOrNull()  // 循环到第一首
        }
    }

    private fun getRandomPlayableSong(): Music? {
        return if (downloadedMusicList.isNotEmpty()) {
            val idx = downloadedMusicList.indexOf(currentMusic)
            val pool = downloadedMusicList.indices.filter { it != idx }
            pool.randomOrNull()?.let { downloadedMusicList[it] }
        } else null
    }

    private fun getNextShuffleSong(): Music? {
        if (!isShuffleEnabled) return getRandomPlayableSong()
        if (shuffleOrder.isEmpty()) {
            val curIdx = downloadedMusicList.indexOf(currentMusic)
            shuffleOrder.addAll(downloadedMusicList.indices.filter { it != curIdx }.shuffled())
        }
        if (shuffleOrder.isEmpty()) return null
        val nextIdx = shuffleOrder.removeAt(0)
        val totalPlayable = (downloadedMusicList.size - 1).coerceAtLeast(1)
        val threshold = kotlin.math.max(1, (totalPlayable * 0.1f).toInt())
        if (shuffleOrder.size <= threshold) {
            val curIdx = downloadedMusicList.indexOf(currentMusic)
            shuffleOrder.addAll(downloadedMusicList.indices.filter { it != curIdx }.shuffled())
        }
        return downloadedMusicList.getOrNull(nextIdx)
    }

    private fun enterGlobalShuffleMode() {
        isGlobalShuffleMode = true
        getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().putBoolean(KEY_GLOBAL_SHUFFLE_MODE, true).apply()
        prevSidebarVisibleInGlobal = isSidebarVisible
        buildGlobalDownloadedList()
        buildGlobalShuffleOrder()
        binding.sidebarContainer.visibility = View.GONE
        isSidebarVisible = false
        binding.showPlaylist.visibility = View.GONE
        binding.btnGlobalShuffle.visibility = View.GONE
        binding.btnExitGlobalShuffle.visibility = View.VISIBLE
        binding.btnViewDislikes.visibility = View.VISIBLE
        binding.btnDislike.visibility = View.VISIBLE
        binding.btnPlayMode.visibility = View.GONE
        binding.btnShuffle.visibility = View.GONE
        updateNextUpLabel()
        startGlobalShuffleIfIdle()
    }

    private fun exitGlobalShuffleMode() {
        isGlobalShuffleMode = false
        getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().putBoolean(KEY_GLOBAL_SHUFFLE_MODE, false).apply()
        globalDownloadedMusicList.clear()
        globalShuffleOrder.clear()
        binding.sidebarContainer.visibility = if (prevSidebarVisibleInGlobal) View.VISIBLE else View.GONE
        isSidebarVisible = prevSidebarVisibleInGlobal
        binding.showPlaylist.visibility = if (prevSidebarVisibleInGlobal) View.GONE else View.VISIBLE
        binding.btnGlobalShuffle.visibility = View.VISIBLE
        binding.btnExitGlobalShuffle.visibility = View.GONE
        binding.btnViewDislikes.visibility = View.GONE
        binding.btnDislike.visibility = View.GONE
        binding.btnPlayMode.visibility = View.VISIBLE
        binding.btnShuffle.visibility = View.VISIBLE
        binding.tvNextUp.visibility = View.GONE
    }

    private fun buildGlobalDownloadedList() {
        val allMusics = if (allPlaylists.isNotEmpty()) {
            allPlaylists.flatMap { it.musics }
        } else {
            musicList
        }
        val distinct = allMusics.distinctBy { it.id }
        globalDownloadedMusicList.clear()
        globalDownloadedMusicList.addAll(distinct.filter { FileUtils.isValidFile(this, it) && !dislikedMusicIds.contains(it.id) })
    }

    private fun startGlobalShuffleIfIdle() {
        if (!isGlobalShuffleMode) return
        if (globalDownloadedMusicList.isEmpty()) {
            Toast.makeText(this, "没有可播放的歌曲", Toast.LENGTH_SHORT).show()
            return
        }
        if (currentMusic == null) {
            val next = getNextGlobalShuffleSong() ?: globalDownloadedMusicList.firstOrNull()
            if (next != null) {
                playMusic(next)
                updateNextUpLabel()
            }
        }
    }

    private fun buildGlobalShuffleOrder() {
        globalShuffleOrder.clear()
        val curIdx = globalDownloadedMusicList.indexOf(currentMusic)
        globalShuffleOrder.addAll(globalDownloadedMusicList.indices.filter { it != curIdx })
        globalShuffleOrder.shuffle()
    }

    private fun rebuildGlobalQueue() {
        buildGlobalDownloadedList()
        buildGlobalShuffleOrder()
    }

    private fun getNextGlobalShuffleSong(): Music? {
        if (globalDownloadedMusicList.isEmpty()) return null
        if (globalShuffleOrder.isEmpty()) {
            buildGlobalShuffleOrder()
        }
        if (globalShuffleOrder.isEmpty()) return null
        val nextIdx = globalShuffleOrder.removeAt(0)
        val totalPlayable = (globalDownloadedMusicList.size - 1).coerceAtLeast(1)
        val threshold = kotlin.math.max(1, (totalPlayable * 0.1f).toInt())
        if (globalShuffleOrder.size <= threshold) {
            val curIdx = globalDownloadedMusicList.indexOf(currentMusic)
            globalShuffleOrder.addAll(globalDownloadedMusicList.indices.filter { it != curIdx }.shuffled())
        }
        return globalDownloadedMusicList.getOrNull(nextIdx)
    }

    private fun peekNextGlobalShuffleSong(): Music? {
        if (globalDownloadedMusicList.isEmpty()) return null
        val idx = globalShuffleOrder.firstOrNull() ?: return null
        return globalDownloadedMusicList.getOrNull(idx)
    }

    private fun updateNextUpLabel() {
        if (!isGlobalShuffleMode) {
            binding.tvNextUp.visibility = View.GONE
            return
        }
        val next = peekNextGlobalShuffleSong()
        if (next != null) {
            binding.tvNextUp.visibility = View.VISIBLE
            binding.tvNextUp.text = "下一首：${next.name} - ${next.singer}"
        } else {
            binding.tvNextUp.visibility = View.VISIBLE
            binding.tvNextUp.text = "下一首：无"
        }
    }

    private fun showDislikedDialog() {
        val allMusics = allPlaylists.flatMap { it.musics }.distinctBy { it.id }
        val disliked = allMusics.filter { dislikedMusicIds.contains(it.id) }
        val names = disliked.map { "${it.name} - ${it.singer}" }.toTypedArray()
        val checked = BooleanArray(names.size) { false }
        MaterialAlertDialogBuilder(this)
            .setTitle("不喜欢")
            .setMultiChoiceItems(names, checked) { _, which, isChecked ->
                checked[which] = isChecked
            }
            .setNegativeButton("关闭", null)
            .setPositiveButton("移除") { _, _ ->
                val toRemove = disliked.indices.filter { checked[it] }
                toRemove.forEach { i ->
                    dislikedMusicIds.remove(disliked[i].id)
                }
                LocalStorage.saveDislikedIds(this, dislikedMusicIds.toList())
                if (isGlobalShuffleMode) {
                    rebuildGlobalQueue()
                    updateNextUpLabel()
                }
            }
            .show()
    }

    private fun startVolumeAnimation() {
        // 取消之前的音量动画
        volumeAnimator?.cancel()

        // 创建新的音量动画
        volumeAnimator = ValueAnimator.ofFloat(0f, 1f).apply {
            duration = 800  // 渐入时长，可以根据需要调整
            interpolator = AccelerateDecelerateInterpolator()
            addUpdateListener { animation ->
                player?.volume = animation.animatedValue as Float
            }
            start()
        }
    }

    override fun onDestroy() {
        // 在Activity销毁前保存播放状态
        savePlaybackState()
        
        // 清理抽屉监听器
        drawerListener?.let { binding.drawerLayout.removeDrawerListener(it) }
        
        // 清理设置抽屉视图
        settingsDrawerView?.let { 
            binding.drawerLayout.removeView(it)
            settingsDrawerView = null
        }
        
        // 清理加载对话框
        dismissLoadingDialog()
        
        super.onDestroy()
        unregisterReceiver(onDownloadComplete)
        scope.cancel()
        player?.release()
        player = null
        timeHandler.removeCallbacks(timeRunnable)
        progressAnimator?.cancel()
        progressAnimator = null
        volumeAnimator?.cancel()
        volumeAnimator = null
        clearPlayHistory()  // 添加这一行
    }

    override fun onPause() {
        // 在应用进入后台时也保存状态
        savePlaybackState()
        savePlayModePrefs()
        super.onPause()
    }

    override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
        // 调试用，打印按键码
        Log.d("PlayerActivity", "KeyCode: $keyCode")
//        Toast.makeText(this, "onKeyDown KeyCode: $keyCode", Toast.LENGTH_LONG).show()
        return when (keyCode) {
            KeyEvent.KEYCODE_MEDIA_NEXT,
            KeyEvent.KEYCODE_MEDIA_STEP_FORWARD,
            KeyEvent.KEYCODE_MEDIA_SKIP_FORWARD,
            KeyEvent.KEYCODE_MEDIA_FAST_FORWARD,
            KeyEvent.KEYCODE_DPAD_RIGHT -> {
                playNextSong()
                true
            }

            KeyEvent.KEYCODE_MEDIA_PREVIOUS,
            KeyEvent.KEYCODE_MEDIA_STEP_BACKWARD,
            KeyEvent.KEYCODE_MEDIA_SKIP_BACKWARD,
            KeyEvent.KEYCODE_MEDIA_REWIND,
            KeyEvent.KEYCODE_DPAD_LEFT -> {
                playPreviousSong()
                true
            }

            else -> super.onKeyDown(keyCode, event)
        }
    }

    private fun syncPlaylist() {
        scope.launch {
            try {
                val response = apiService.getPlaylist()
                if (response.code == 0 && response.data.isNotEmpty()) {
                    // 保存所有歌单
                    allPlaylists = response.data
                    // 如果当前没有选中的歌单，选择第一个
                    if (currentPlaylist == null) {
                        currentPlaylist = allPlaylists.firstOrNull()
                    } else {
                        // 如果有选中的歌单，找到对应的新歌单
                        currentPlaylist = allPlaylists.find { it.id == currentPlaylist?.id }
                            ?: allPlaylists.firstOrNull()
                    }
                    // 保存到本地
                    LocalStorage.savePlaylists(this@PlayerActivity, response)
                    // 更新显示
                    updatePlaylistDisplay()
                    Toast.makeText(this@PlayerActivity, "同步歌单成功", Toast.LENGTH_SHORT).show()
                } else {
                    Toast.makeText(
                        this@PlayerActivity,
                        "同步歌单失败: ${response.msg}",
                        Toast.LENGTH_SHORT
                    ).show()
                }
            } catch (e: Exception) {
                Log.e("PlayerActivity", "Error syncing playlist", e)
                Toast.makeText(this@PlayerActivity, "同步歌单失败: ${e.message}", Toast.LENGTH_SHORT)
                    .show()
            }
        }
    }

    private fun checkUpdate() {
        scope.launch {
            try {
                binding.progressBar.visibility = View.VISIBLE
                val versionInfo = withContext(Dispatchers.IO) {
                    apiService.checkUpdate()
                }

                // 显示更新对话框
                MaterialAlertDialogBuilder(this@PlayerActivity)
                    .setTitle("发现新版本")
                    .setMessage(
                        """
                        当前版本: 1.0
                        最新版本：${versionInfo.version}
                    """.trimIndent()
                    )
                    .setNegativeButton("取消") { dialog, _ ->
                        dialog.dismiss()
                    }
                    .setPositiveButton("更新") { dialog, _ ->
                        // 开始下载更新
                        startDownloadUpdate(versionInfo.downloadUrl)
                        dialog.dismiss()
                    }
                    .show()

            } catch (e: Exception) {
                Toast.makeText(
                    this@PlayerActivity,
                    "检查更新失败: ${e.message}",
                    Toast.LENGTH_SHORT
                ).show()
            } finally {
                binding.progressBar.visibility = View.GONE
            }
        }
    }

    @SuppressLint("SetTextI18s")
    private fun startDownloadUpdate(downloadUrl: String) {
        // 显示下载进度面板
        binding.updateNotificationPanel.visibility = View.VISIBLE
        binding.tvUpdateProgress.text = "准备下载..."

        scope.launch {
            try {
                val file = File(
                    Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
                    "car_music_update.apk"
                )

                val success: Boolean
                try {
                    success = FileDownloader.downloadFile(
                        url = downloadUrl,
                        file = file,
                        onProgress = { progress ->
                            binding.updateProgressBar.progress = progress
                            binding.tvUpdateProgress.text = "${progress}%"
                        }
                    )
                } catch (e: Exception) {
                    Log.e("PlayerActivity", "Download error", e)
                    binding.tvUpdateProgress.text = "下载失败: ${e.message}"
                    return@launch
                }

                if (success) {
                    binding.tvUpdateProgress.text = "下载完成"
                    // 显示安装提示
                    showInstallPrompt()
                } else {
                    binding.tvUpdateProgress.text = "下载失败"
                }
            } catch (e: Exception) {
                Log.e("PlayerActivity", "Download failed", e)
                binding.tvUpdateProgress.text = "下载失败: ${e.message}"
            }
        }
    }

    private fun showInstallPrompt() {
        binding.updateNotificationPanel.visibility = View.GONE
        MaterialAlertDialogBuilder(this)
            .setTitle("下载完成")
            .setMessage("是否立即安装新版本？")
            .setNegativeButton("取消", null)
            .setPositiveButton("安装") { _, _ ->
                installApk()
            }
            .show()
    }

    private fun installApk() {
        try {
            val file = File(
                Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
                "car_music_update.apk"
            )

            // 使用 FileProvider 获取文件 URI
            val apkUri = FileProvider.getUriForFile(
                this,
                "${applicationContext.packageName}.provider",
                file
            )

            val intent = Intent(Intent.ACTION_VIEW).apply {
                setDataAndType(apkUri, "application/vnd.android.package-archive")
                flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_GRANT_READ_URI_PERMISSION
                addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            }
            startActivity(intent)
        } catch (e: Exception) {
            Log.e("PlayerActivity", "Install APK failed", e)
            Toast.makeText(this, "安装失败: ${e.message}", Toast.LENGTH_SHORT).show()
        }
    }

    private fun savePlaybackState() {
        savePlayModePrefs()
        player?.let { player ->
            currentMusic?.let { music ->
                getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().apply {
                    putInt(KEY_LAST_MUSIC_ID, music.id)
                    putLong(KEY_LAST_POSITION, player.currentPosition)
                    putInt(KEY_LAST_PLAYLIST_ID, currentPlaylist?.id ?: -1)
                    apply()
                }
            }
        }
    }

    private fun restorePlaybackState() {
        val prefs = getSharedPreferences(PREFS_NAME, MODE_PRIVATE)
        val savedModeName = prefs.getString(KEY_PLAY_MODE, PlayMode.SEQUENCE.name)
        val savedShuffle = prefs.getBoolean(KEY_SHUFFLE_ENABLED, false)
        val savedGlobalShuffle = prefs.getBoolean(KEY_GLOBAL_SHUFFLE_MODE, false)
        isShuffleEnabled = savedShuffle
        currentPlayMode = if (savedShuffle) {
            PlayMode.SHUFFLE
        } else {
            try {
                PlayMode.valueOf(savedModeName ?: PlayMode.SEQUENCE.name)
            } catch (e: Exception) {
                PlayMode.SEQUENCE
            }
        }
        updatePlayModeUI()
        if (isShuffleEnabled) {
            shuffleOrder = mutableListOf<Int>().apply {
                val curIdx = downloadedMusicList.indexOf(currentMusic)
                addAll(downloadedMusicList.indices.filter { it != curIdx })
                shuffle()
            }
        }
        if (savedGlobalShuffle) {
            enterGlobalShuffleMode()
            if (player?.isPlaying != true && currentMusic == null) {
                startGlobalShuffleIfIdle()
            }
        }
        val lastMusicId = prefs.getInt(KEY_LAST_MUSIC_ID, -1)
        val lastPosition = prefs.getLong(KEY_LAST_POSITION, 0)

        if (lastMusicId != -1) {
            // 查找上次播放的歌曲
            musicList.find { it.id == lastMusicId }?.let { music ->
                if (FileUtils.isMusicFileExists(this, music)) {
                    playMusic(music)
                    // 延迟设置播放位置，确保播放器已经准备好
                    player?.let { exoPlayer ->
                        exoPlayer.addListener(object : Player.Listener {
                            override fun onPlaybackStateChanged(state: Int) {
                                if (state == Player.STATE_READY) {
                                    exoPlayer.seekTo(lastPosition)
                                    exoPlayer.removeListener(this)
                                }
                            }
                        })
                    }
                }
            }
        }

        // 如果没有恢复到具体歌曲，确保播放器加载一个可播放媒体
        if (player != null && currentMusic == null) {
            // 优先使用当前歌单第一首已下载歌曲
            musicList.find { FileUtils.isValidFile(this, it) }?.let { m ->
                selectMusic(m, autoPlay = false)
            }
        } else if (player != null && currentMusic != null) {
            // 确保当前歌曲已经绑定到播放器
            selectMusic(currentMusic!!, autoPlay = false)
        }
    }

    private fun savePlayModePrefs() {
        getSharedPreferences(PREFS_NAME, MODE_PRIVATE).edit().apply {
            putString(KEY_PLAY_MODE, currentPlayMode.name)
            putBoolean(KEY_SHUFFLE_ENABLED, isShuffleEnabled)
            putBoolean(KEY_GLOBAL_SHUFFLE_MODE, isGlobalShuffleMode)
            apply()
        }
    }

    private suspend fun loadCoverImage(music: Music) {
        withContext(Dispatchers.IO) {
            try {
                Log.d("PlayerActivity", "Loading cover for music: ${music.name}, has covers: ${!music.covers.isNullOrEmpty()}")
                
                // 加载封面图片
                val bitmap = when {
                    // 1. 如果歌曲有封面，优先使用歌曲的封面
                    music.covers?.isNotEmpty() == true -> {
                        Log.d("PlayerActivity", "Music has covers, trying to use music cover first")
                        val coverFile = FileUtils.getCoverFile(
                            this@PlayerActivity,
                            music.covers.split(",").firstOrNull() ?: ""
                        )
                        if (coverFile.exists()) {
                            Log.d("PlayerActivity", "Using music cover file: ${coverFile.name}")
                            BitmapFactory.decodeFile(coverFile.absolutePath)
                        } else {
                            Log.d("PlayerActivity", "Music cover file not found, trying cached covers")
                            // 歌曲封面文件不存在，尝试使用缓存的封面
                            getRandomCachedCoverBitmap() ?: run {
                                Log.d("PlayerActivity", "No cached covers available, using default")
                                // 如果没有缓存封面，使用默认封面
                                assets.open("bg/default_cover.png")
                                    .use { BitmapFactory.decodeStream(it) }
                            }
                        }
                    }
                    
                    // 2. 如果歌曲没有封面，从本地缓存的封面列表中随机获取一个
                    allCovers.isNotEmpty() -> {
                        Log.d("PlayerActivity", "Music has no covers, using random cached cover")
                        getRandomCachedCoverBitmap() ?: run {
                            Log.d("PlayerActivity", "Failed to get random cached cover, using default")
                            // 如果随机获取失败，使用默认封面
                            assets.open("bg/default_cover.png")
                                .use { BitmapFactory.decodeStream(it) }
                        }
                    }

                    // 3. 如果本地没有封面或者封面数量是0，使用默认封面
                    else -> {
                        Log.d("PlayerActivity", "No cached covers available, using default cover")
                        assets.open("bg/default_cover.png")
                            .use { BitmapFactory.decodeStream(it) }
                    }
                }

                // 提取主题颜色
                val themeColors = ColorUtils.extractThemeColors(bitmap)

                withContext(Dispatchers.Main) {
                    // 更新封面图片
                    binding.ivCover.setImageBitmap(bitmap)

                    // 更新背景颜色
                    binding.root.setBackgroundColor(themeColors.backgroundColor)
                    
                    // 更新侧边栏毛玻璃效果
                    binding.sidebarBlurView.setImageBitmap(bitmap)
                    // 根据主题色调整侧边栏遮罩透明度
                    val overlayAlpha = if (ColorUtils.isLightColor(themeColors.backgroundColor)) 0x60 else 0x40
                    binding.sidebarOverlay.setBackgroundColor((overlayAlpha shl 24) or 0x000000)

                    // 更新毛玻璃背景
                    binding.blurView.setImageBitmap(bitmap)

                    // 更新进度条颜色
                    updateSeekBarColors(themeColors.accentColor)

                    // 更新歌词颜色
                    binding.lrcView.setHighlightColor(themeColors.accentColor)
                    binding.lrcView.setNormalColor(Color.parseColor("#66FFFFFF")) // 普通歌词使用更灰的白色
                }
            } catch (e: Exception) {
                Log.e("PlayerActivity", "Error loading cover image", e)
                // 出错时使用默认封面
                withContext(Dispatchers.Main) {
                    try {
                        val defaultBitmap = assets.open("bg/default_cover.png").use { BitmapFactory.decodeStream(it) }
                        binding.ivCover.setImageBitmap(defaultBitmap)
                        binding.blurView.setImageBitmap(defaultBitmap)
                        
                        // 更新侧边栏毛玻璃背景
                        binding.sidebarBlurView.setImageBitmap(defaultBitmap)
                        
                        // 提取默认封面的主题色并应用
                        val colors = ColorUtils.extractThemeColors(defaultBitmap)
                        updateThemeColors(colors.backgroundColor, colors.accentColor)
                    } catch (e2: Exception) {
                        Log.e("PlayerActivity", "Error loading default cover in updateCoverImage", e2)
                    }
                }
            }
        }
    }

    private fun updateSeekBarColors(accentColor: Int) {
        // 更新进度条的drawable
        val progressDrawable = binding.seekBar.progressDrawable as? LayerDrawable
        progressDrawable?.findDrawableByLayerId(android.R.id.progress)?.let { progress ->
            when (progress) {
                is GradientDrawable -> {
                    progress.colors = intArrayOf(accentColor, Color.WHITE)
                    progress.orientation = GradientDrawable.Orientation.LEFT_RIGHT
                }

                is ScaleDrawable -> {
                    // 获取 ScaleDrawable 的内部 Drawable
                    val drawable = progress.drawable
                    if (drawable is GradientDrawable) {
                        drawable.colors = intArrayOf(accentColor, Color.WHITE)
                        drawable.orientation = GradientDrawable.Orientation.LEFT_RIGHT
                    }
                }
            }
        }

        // 更新thumb的颜色
        binding.seekBar.thumb?.setTint(Color.WHITE)
    }

    private fun downloadNewCovers(newCovers: List<Cover>) {
        scope.launch {
            var successCount = 0
            val totalCount = newCovers.size
            
            withContext(Dispatchers.Main) {
                Toast.makeText(this@PlayerActivity, "开始下载 $totalCount 个新封面...", Toast.LENGTH_SHORT).show()
            }
            
            newCovers.forEachIndexed { index, cover ->
                try {
                    val coverFile = FileUtils.getCoverFile(this@PlayerActivity, cover.url)
                    
                    // 如果文件已存在且大小合理，跳过下载
                    if (coverFile.exists() && coverFile.length() > 1024) {
                        successCount++
                        return@forEachIndexed
                    }
                    
                    // 确保目录存在
                    coverFile.parentFile?.mkdirs()
                    
                    // 下载封面文件
                    val success = withContext(Dispatchers.IO) {
                        FileDownloader.downloadFile(cover.url, coverFile) { progress ->
                            // 可以在这里更新进度，如果需要的话
                        }
                    }
                    
                    if (success && coverFile.exists() && coverFile.length() > 0) {
                        successCount++
                    }
                    
                } catch (e: Exception) {
                    Log.e("PlayerActivity", "Error downloading cover: ${cover.name}", e)
                }
                
                // 每下载几个封面更新一次进度提示
                if ((index + 1) % 3 == 0 || index == totalCount - 1) {
                    withContext(Dispatchers.Main) {
                        val progressText = "下载封面中... ($successCount/${index + 1})"
                        Toast.makeText(this@PlayerActivity, progressText, Toast.LENGTH_SHORT).show()
                    }
                }
            }
            
            // 下载完成后显示结果
            withContext(Dispatchers.Main) {
                val message = "封面下载完成：成功 $successCount/$totalCount"
                Toast.makeText(this@PlayerActivity, message, Toast.LENGTH_LONG).show()
                
                // 重新加载封面信息
                loadCovers()
            }
        }
    }

    // 添加音频焦点管理
    private fun requestAudioFocus() {
        val audioManager = getSystemService(AUDIO_SERVICE) as AudioManager
        val result = audioManager.requestAudioFocus(
            audioFocusChangeListener,
            AudioManager.STREAM_MUSIC,
            AudioManager.AUDIOFOCUS_GAIN
        )
        if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) {
            // 获得焦点后的处理
        }
    }

    private val audioFocusChangeListener = AudioManager.OnAudioFocusChangeListener { focusChange ->
        when (focusChange) {
            AudioManager.AUDIOFOCUS_LOSS -> {
                // 失去焦点较长时间
                player?.pause()
                updatePlayPauseState(false)
            }

            AudioManager.AUDIOFOCUS_LOSS_TRANSIENT -> {
                // 暂时失去焦点
                player?.pause()
                updatePlayPauseState(false)
            }

            AudioManager.AUDIOFOCUS_GAIN -> {
                // 重新获得焦点
                player?.play()
                updatePlayPauseState(true)
            }
        }
    }

    private fun updatePlayPauseState(isPlaying: Boolean) {
        binding.btnPlayPause.setImageResource(
            if (isPlaying) R.drawable.ic_pause
            else R.drawable.ic_play
        )

        // 更新歌曲列表中的播放动画
        currentMusic?.let { music ->
            musicAdapter.updatePlayingState(music.id, isPlaying)
        }
    }

    private fun startTimeUpdate() {
        updateDateTime() // 立即更新一次
        timeHandler.post(timeRunnable)
    }

    private fun updateDateTime() {
        val calendar = Calendar.getInstance()
        val dateFormat = SimpleDateFormat("M月d日 E HH:mm", Locale.getDefault())
        binding.tvCurrentDateTime.text = dateFormat.format(calendar.time)
    }

    private fun updatePlayModeUI() {
        when (currentPlayMode) {
            PlayMode.SEQUENCE -> {
                binding.btnPlayMode.setImageResource(R.drawable.ic_repeat)
                binding.btnPlayMode.alpha = 0.5f
                binding.btnShuffle.alpha = 0.5f
            }

            PlayMode.REPEAT_ONE -> {
                binding.btnPlayMode.setImageResource(R.drawable.ic_repeat_one)
                binding.btnPlayMode.alpha = 1f
                binding.btnShuffle.alpha = 0.5f
            }

            PlayMode.SHUFFLE -> {
                binding.btnPlayMode.setImageResource(R.drawable.ic_repeat)
                binding.btnPlayMode.alpha = 0.5f
                binding.btnShuffle.alpha = 1f
            }
        }
    }

    // 新增：从本地缓存的封面列表中随机获取一个封面图片
    private suspend fun getRandomCachedCoverBitmap(): android.graphics.Bitmap? {
        return withContext(Dispatchers.IO) {
            try {
                if (allCovers.isEmpty()) {
                    Log.d("PlayerActivity", "No cached covers available")
                    return@withContext null
                }

                // 获取所有可用的封面（本地文件存在的）
                val availableCovers = allCovers.filter { cover ->
                    val file = FileUtils.getCoverFile(this@PlayerActivity, cover.url)
                    file.exists()
                }

                if (availableCovers.isEmpty()) {
                    Log.d("PlayerActivity", "No local cover files found")
                    return@withContext null
                }

                Log.d("PlayerActivity", "Found ${availableCovers.size} available covers, lastUsedCoverId: $lastUsedCoverId")

                // 根据可用封面数量决定选择策略
                val selectedCover = when {
                    // 如果只有一张封面，直接使用
                    availableCovers.size == 1 -> {
                        Log.d("PlayerActivity", "Only one cover available, using it")
                        availableCovers.first()
                    }
                    // 如果有多张封面，智能选择
                    else -> {
                        // 尝试最多3次来避免选择到相同的封面
                        var attempts = 0
                        var selectedCover: Cover? = null
                        
                        while (attempts < 3 && selectedCover == null) {
                            attempts++
                            
                            // 如果是第一次选择或者没有上次使用的记录，直接随机选择
                            val candidates = if (lastUsedCoverId != null && availableCovers.size > 1) {
                                availableCovers.filter { it.id != lastUsedCoverId }
                            } else {
                                availableCovers
                            }
                            
                            if (candidates.isNotEmpty()) {
                                selectedCover = candidates.random()
                                Log.d("PlayerActivity", "Attempt $attempts: selected cover id=${selectedCover.id}")
                            } else {
                                // 如果过滤后没有候选封面，从所有可用封面中选择
                                selectedCover = availableCovers.random()
                                Log.d("PlayerActivity", "Attempt $attempts: fallback to any cover id=${selectedCover.id}")
                            }
                            
                            // 如果选择的封面和上次不同，或者已经尝试了3次，就使用这个封面
                            if (selectedCover.id != lastUsedCoverId || attempts >= 3) {
                                break
                            } else {
                                // 如果还是选择到了相同的封面，重试
                                selectedCover = null
                                Log.d("PlayerActivity", "Same cover selected, retrying...")
                            }
                        }
                        
                        selectedCover ?: availableCovers.random()
                    }
                }

                // 记录使用的封面ID
                lastUsedCoverId = selectedCover.id
                Log.d("PlayerActivity", "Final selected cover: id=${selectedCover.id}, name=${selectedCover.name}")

                // 加载封面文件
                val coverFile = FileUtils.getCoverFile(this@PlayerActivity, selectedCover.url)
                BitmapFactory.decodeFile(coverFile.absolutePath)

            } catch (e: Exception) {
                Log.e("PlayerActivity", "Error getting random cached cover", e)
                null
            }
        }
    }

    // 新增：随机切换封面方法
    private fun randomSwitchCover() {
        // 防止重复点击
        if (isCoverSwitching) return
        
        scope.launch {
            try {
                isCoverSwitching = true
                
                // 添加触觉反馈
                withContext(Dispatchers.Main) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                        binding.ivCover.performHapticFeedback(android.view.HapticFeedbackConstants.CONTEXT_CLICK)
                    } else {
                        @Suppress("DEPRECATION")
                        binding.ivCover.performHapticFeedback(android.view.HapticFeedbackConstants.VIRTUAL_KEY)
                    }
                }
                
                // 在后台加载新封面
                val randomBitmap = getRandomCachedCoverBitmap()
                
                if (randomBitmap != null) {
                    // 提取主题颜色
                    val themeColors = ColorUtils.extractThemeColors(randomBitmap)

                    withContext(Dispatchers.Main) {
                        // 创建临时ImageView用于过渡动画
                        val tempImageView = android.widget.ImageView(this@PlayerActivity).apply {
                            layoutParams = binding.ivCover.layoutParams
                            scaleType = binding.ivCover.scaleType
                            setImageBitmap(randomBitmap)
                            alpha = 0f
                            scaleX = 0.95f // 初始稍微缩小
                            scaleY = 0.95f
                        }
                        
                        // 添加临时ImageView到CardView中
                        val cardView = binding.coverCardView
                        cardView.addView(tempImageView)
                        
                        // 动画参数
                        val animationDuration = 400L
                        
                        // 新封面淡入 + 缩放效果
                        tempImageView.animate()
                            .alpha(1f)
                            .scaleX(1f)
                            .scaleY(1f)
                            .setDuration(animationDuration)
                            .setInterpolator(AccelerateDecelerateInterpolator())
                            .start()
                        
                        // 旧封面淡出 + 轻微缩放
                        binding.ivCover.animate()
                            .alpha(0f)
                            .scaleX(1.05f)
                            .scaleY(1.05f)
                            .setDuration(animationDuration)
                            .setInterpolator(AccelerateDecelerateInterpolator())
                            .withEndAction {
                                try {
                                    // 动画完成后，替换原来的封面并清理临时视图
                                    binding.ivCover.setImageBitmap(randomBitmap)
                                    binding.ivCover.alpha = 1f
                                    binding.ivCover.scaleX = 1f
                                    binding.ivCover.scaleY = 1f
                                    
                                    // 安全移除临时视图
                                    if (tempImageView.parent == cardView) {
                                        cardView.removeView(tempImageView)
                                    }
                                    
                                    // 重置点击状态
                                    isCoverSwitching = false
                                } catch (e: Exception) {
                                    Log.e("PlayerActivity", "Error in animation end action", e)
                                    isCoverSwitching = false
                                }
                            }
                            .start()

                        // 背景颜色渐变动画（延迟启动以获得更流畅的效果）
                        binding.ivCover.postDelayed({
                            ValueAnimator.ofArgb(
                                (binding.root.background as? ColorDrawable)?.color ?: Color.BLACK,
                                themeColors.backgroundColor
                            ).apply {
                                duration = 500L // 稍微延长背景色过渡时间
                                interpolator = AccelerateDecelerateInterpolator()
                                addUpdateListener { animator ->
                                    binding.root.setBackgroundColor(animator.animatedValue as Int)
                                }
                                start()
                            }
                        }, 100L) // 延迟100ms启动
                        
                        // 更新其他UI元素（延迟执行避免阻塞主动画）
                        binding.ivCover.postDelayed({
                            try {
                                // 更新侧边栏毛玻璃效果
                                binding.sidebarBlurView.setImageBitmap(randomBitmap)
                                
                                // 根据主题色调整侧边栏遮罩透明度
                                val overlayAlpha = if (ColorUtils.isLightColor(themeColors.backgroundColor)) 0x60 else 0x40
                                binding.sidebarOverlay.setBackgroundColor((overlayAlpha shl 24) or 0x000000)

                                // 更新毛玻璃背景
                                binding.blurView.setImageBitmap(randomBitmap)

                                // 更新进度条颜色
                                updateSeekBarColors(themeColors.accentColor)

                                // 更新歌词颜色
                                binding.lrcView.setHighlightColor(themeColors.accentColor)
                                binding.lrcView.setNormalColor(Color.parseColor("#66FFFFFF"))
                            } catch (e: Exception) {
                                Log.e("PlayerActivity", "Error updating UI elements", e)
                            }
                        }, 150L) // 延迟150ms更新其他UI
                    }
                } else {
                    withContext(Dispatchers.Main) {
                        isCoverSwitching = false
                        Toast.makeText(this@PlayerActivity, "暂无可用封面", Toast.LENGTH_SHORT).show()
                    }
                }
            } catch (e: Exception) {
                Log.e("PlayerActivity", "Error switching cover", e)
                withContext(Dispatchers.Main) {
                    isCoverSwitching = false
                    Toast.makeText(this@PlayerActivity, "切换封面失败", Toast.LENGTH_SHORT).show()
                }
            }
        }
    }
}